widget: Fix can-focus
authorMatthias Clasen <mclasen@redhat.com>
Wed, 27 Jan 2021 04:43:11 +0000 (23:43 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Wed, 27 Jan 2021 04:45:06 +0000 (23:45 -0500)
Setting can-focus to FALSE on a widget is supposed
to prevent focus from entering the entire subtree.
So when we grab focus directly to a widget, we need
to check the can-focus flag not just of the widget
itself, but all its ancestors.

Fixes: #3610
gtk/gtkwidget.c

index 0daeef7a6df2d0151a747aa79a5790f5733ec38c..0186968bd7d6a7127f36c7cc62577f95a6b399de 100644 (file)
@@ -4390,13 +4390,27 @@ gtk_widget_can_activate (GtkWidget *self)
   return FALSE;
 }
 
+static gboolean
+get_effective_can_focus (GtkWidget *widget)
+{
+  GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+
+  if (!priv->can_focus)
+    return FALSE;
+
+  if (priv->parent)
+    return get_effective_can_focus (priv->parent);
+
+  return TRUE;
+}
+
 static gboolean
 gtk_widget_real_mnemonic_activate (GtkWidget *widget,
                                    gboolean   group_cycling)
 {
   if (!group_cycling && gtk_widget_can_activate (widget))
     gtk_widget_activate (widget);
-  else if (gtk_widget_get_can_focus (widget))
+  else if (get_effective_can_focus (widget))
     return gtk_widget_grab_focus (widget);
   else
     {
@@ -4782,7 +4796,7 @@ gtk_widget_grab_focus (GtkWidget *widget)
   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
 
   if (!gtk_widget_is_sensitive (widget) ||
-      !gtk_widget_get_can_focus (widget) ||
+      !get_effective_can_focus (widget) ||
       widget->priv->root == NULL)
     return FALSE;